package com.h3bpm.kumhosunny.crm.controller.dingtalk;

import OThinker.Common.DotNetToJavaStringHelper;
import OThinker.Common.EncodingUtil;
import OThinker.Common.Organization.Models.User;
import OThinker.Common.Organization.enums.PrivacyLevel;
import OThinker.Common.Security.SHAEncryptor;
import OThinker.H3.Controller.ControllerBase;
import OThinker.H3.Entity.Notification.IDingTalkAdapter;
import OThinker.H3.Entity.Settings.CustomSetting;
import OThinker.H3.Entity.Settings.ISettingManager;
import com.h3bpm.base.authc.NoAuth;
import com.h3bpm.base.operator.UserInfoOperator;
import com.h3bpm.base.res.ResBody;
import com.h3bpm.base.user.UserValidator;
import com.h3bpm.base.user.UserValidatorFactory;
import com.h3bpm.base.util.AppConfig;
import com.h3bpm.base.util.AppUtility;
import com.h3bpm.base.util.Sessions;
import com.h3bpm.kumhosunny.common.utils.HttpRequestUtils;
import com.h3bpm.kumhosunny.common.utils.SqlUtil;
import com.h3bpm.mobile.vo.MobileUser;
import data.DataTable;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @authormi
 * @date2019/12/4
 */
@Controller
@RequestMapping({"/Portal/DingtalkController"})
public class DingtalkController   {

    @Autowired
    private UserInfoOperator userInfoOperator;


    final int length = 8 ;

    @Value("${ddagentId}")
    public String ddAgentId;

    /**
     * @Fields serialVersionUID :
     */
    private static final long serialVersionUID = 1951305555362177857L;

    public IDingTalkAdapter adapter;
    public IDingTalkAdapter getDingAdapter() throws Exception{
        if(adapter != null){
            return adapter;
        } else {

            adapter = AppUtility.getEngine().getDingTalkAdapter();
            return adapter;
        }
    }

    private String ranNoce;
    public String getRanNoce(){
        if (DotNetToJavaStringHelper.isNullOrEmpty(ranNoce)){
            ranNoce = this.randNonce();
            return ranNoce;
        }
        return ranNoce;
    }

    private String timeStamp;
    public String getTimeStamp() throws Exception{

        if (DotNetToJavaStringHelper.isNullOrEmpty(timeStamp))
        {
            timeStamp = this.timeStamp();
            return timeStamp;
        }
        return timeStamp;
    }

    /**
     * @Title: randNonce
     * @Description: 返回一个八位的随机号，用于签名
     * @Param: @return
     * @Return: String
     * @throws
     */
    private String randNonce(){
        String result = "";
        Random random  =   new Random((Long)System.currentTimeMillis()) ;
        String textArray = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        for(int i = 0; i < length; i++){
            //update by zjengyj (int) System.currentTimeMillis()
            //時間戳可能大於int範圍。
            int temp =Math.abs(random.nextInt())% textArray.length();
            result = result + textArray.substring(temp, temp+1);
        }
        return result;
    }

    /**
     * @throws Exception
     * @Title: timeStamp
     * @Description: 时间戳的随机数,用户签名
     * @Param: @return
     * @Return: String
     * @throws
     */
    private String timeStamp() throws Exception{
        //TODO
        //update by zhengyj  返回当前时间戳
        return   String.valueOf((new Date()).getTime());
    }


    /**
     * @throws Exception
     * @Title: GetSignaure
     * @Description: 获取签名字符串hash值
     * @Param: @param url
     * @Param: @return
     * @Return: String
     * @throws
     */
    private String GetSignaure(String url) throws Exception{
        String String1 = "jsapi_ticket={0}&noncestr={1}&timestamp={2}&url={3}";
        //TODO
        String nonce = this.getRanNoce();
        String timestamp = this.getTimeStamp();
        String ticket = this.getDingAdapter().GetJSAPITicket();
        String1 = "jsapi_ticket="+ticket+"&noncestr="+nonce+"&timestamp="+timestamp+"&url="+url;
        String signature = SHAEncryptor.getSHA1(String1);
        return signature;
    }

    /**
     * @Title: GetPortalRoot
     * @Description: 获取根虚拟目录
     * @Param: @return
     * @Return: Object
     * @throws
     */
    public String GetPortalRoot(){
        return AppConfig.getPortalRoot();
    }

    /**
     * 得到签名信息,供前端做签名校验
     * @param url
     * @return ResBody json格式数据
     * @throws Exception
     */
    @NoAuth
    @RequestMapping(value = "/GetSignConfig", method = RequestMethod.GET)
    @ResponseBody
    public ResBody GetSignConfig(String url) throws Exception {
        // 处理当应用目录编码为中文时，发布到钉钉后，访问时却提示登陆失败的问题
        if (!DotNetToJavaStringHelper.isNullOrEmpty(url)) {
            url = EncodingUtil.toUTF8(url);
        }

        ISettingManager settingManager = AppUtility.getEngine().getSettingManager();
        String agentID = ddAgentId;
        String corpId = settingManager.GetCustomSetting(CustomSetting.Setting_DDCorpID);
        Map<String, Object> config = new HashMap<>(5);
        config.put("agentId", agentID);
        config.put("corpId", corpId);
        config.put("timeStamp", getTimeStamp());
        config.put("nonce", getRanNoce());
        config.put("signature", GetSignaure(url));

        return ResBody.buildSuccessResBody(config);
    }

    /**
     * @Title: ValidateLoginForDingTalk
     * @Description: 钉钉集成登录
     * @Param: @param state
     * @Param: @param code
     * @Param: @return
     * @Return: ResBody
     * @throws Exception
     */
    @NoAuth
    @RequestMapping(value="/ValidateLoginForDingTalk",method=RequestMethod.GET)
    @ResponseBody
    public ResBody ValidateLoginForDingTalk(HttpServletRequest request, HttpServletResponse response, String state, String code) throws InstantiationException, IllegalAccessException, Exception{
        User currentUser = null;
        UserValidator userValidator = null;
        String userImage = "";
        // 钉钉登录
        userValidator = UserValidatorFactory.LoginAsDingTalkReturnUserValidator(request,state, code);
        Map<String, Object> result = new HashMap<String, Object>(5);
        if (userValidator == null){
            result.put("Success", false);
        } else {
            currentUser = userValidator.getUser();

            userImage = userValidator.getImagePath();
            MobileUser mobileUser = GetMobileUser(userValidator, currentUser, userImage, "", "");
            //update by ouyangsk 获取用户当前父部门
            result.put("DirectoryUnits", mobileUser == null ? null : userInfoOperator.GetDirectoryUnits(mobileUser.getObjectID(), null));
            result.put("Success", true);
            result.put("PortalRoot",  this.GetPortalRoot());
            result.put("MobileUser", mobileUser);

            if(request.getSession().getAttribute(currentUser.getCode())==null){
                Cookie cookies = new Cookie(currentUser.getCode(),"false");
                cookies.setMaxAge(3600);
                response.addCookie(cookies);
                request.getSession().setAttribute(currentUser.getCode(), cookies);
            }
            // 当前用户登录
            request.getSession().setAttribute(Sessions.GetUserValidator(), userValidator);
            request.getSession().setAttribute(Sessions.GetDingTalkLogin(), true);
            //update by ouyangsk 移动端登陆后设置session不过期
            request.getSession().setMaxInactiveInterval(0);
        }
        return ResBody.buildSuccessResBody(result);
    }

    private MobileUser GetMobileUser(UserValidator sourceUser, User user, String imageUrl, String departmentName, String mobileToken) throws InstantiationException, IllegalAccessException, Exception
    {
        String mobile, officePhone, email, code, wechat;
        mobile = officePhone = email = code = wechat = "";

        if (user.getPrivacyLevel() == PrivacyLevel.PublicToAll
                || (sourceUser != null && user.getPrivacyLevel() == PrivacyLevel.PublicToDept && user.getParentID() == sourceUser.getUser().getParentID())
                || (sourceUser != null && user.getPrivacyLevel() == PrivacyLevel.PublicToDepts && AppUtility.getEngine().getOrganization().IsAncestor(user.getParentID(), sourceUser.getUser().getParentID()))
                || (sourceUser != null && user.getPrivacyLevel() == PrivacyLevel.Confidential && sourceUser.ValidateOrgView(user.getObjectID())))
        {
            mobile = user.getMobile();
            officePhone = user.getOfficePhone();
            email = user.getEmail();
            code = user.getCode();
            wechat = user.getWeChatAccount();
        }
        //update by zhengyj 处理用户头像
        imageUrl = UserValidator.GetUserImagePath(AppUtility.getEngine(), user, AppConfig.getPortalRoot()+"/TempImage/").replace("//", "/");
        if(!DotNetToJavaStringHelper.isNullOrEmpty(imageUrl)){
            imageUrl = "/"+ imageUrl+"?T="+(new Date()).getTime();
        }
        MobileUser tempVar = new MobileUser();
        tempVar.setObjectID(user.getObjectID());
        tempVar.setName(user.getName());
        tempVar.setCode(user.getCode());
        tempVar.setAppellation(user.getAppellation());
        tempVar.setDepartmentName(departmentName);
        tempVar.setEmail(email);
        tempVar.setMobile(mobile);
        tempVar.setImageUrl(imageUrl);
        tempVar.setOfficePhone(officePhone);
        tempVar.setWeChat(wechat);
        tempVar.setMobileToken(mobileToken);
        //update by ouyangsk
        tempVar.setGender(user.getGenderInt());
        tempVar.setParentID(user.getParentID());
        MobileUser mobileUser = tempVar;
        return mobileUser;
    }

    /**
     * @Title: ValidateLoginForDingTalkMobile
     * @Description: 钉钉集成登录,使用用户ObjectID登录
     * @Param: @param state
     * @Param: @param code
     * @Param: @return
     * @Return: JsonResult
     * @throws Exception
     */
    @RequestMapping(value="/ValidateLoginForDingTalkMobile",method=RequestMethod.GET)
    @ResponseBody
    public Object ValidateLoginForDingTalkMobile(HttpServletRequest request,String state, String code) throws InstantiationException, IllegalAccessException, Exception
    {
        AppUtility.getEngine().getLogWriter().Write("DingTalkMobile：进入登录方法-------------------------");
        User currentUser = null;
        UserValidator userValidator = null;
        String userImage = "";
        // 钉钉登录
        //TODO
        userValidator = UserValidatorFactory.LoginAsDingTalkPCAndReturnUserValidator(request,state, code);
        Map<String, Object> result = new HashMap<String, Object>(5);
        if (userValidator == null){
            result.put("Success", false);
        } else {
            currentUser = userValidator.getUser();
            userImage = userValidator.getImagePath();
            MobileUser mobileUser = GetMobileUser(userValidator, currentUser, userImage, "", "");
            result.put("Success", true);
            result.put("MobileUser", mobileUser);
            //TODO
            if(request.getSession().getAttribute(currentUser.getCode())==null){
                Cookie cookies = new Cookie(currentUser.getCode(),"false");
                request.getSession().setAttribute(currentUser.getCode(), cookies);
            }
            // 当前用户登录
            request.getSession().setAttribute(Sessions.GetUserValidator(), userValidator);
        }
        return result;
    }

}
